package com.bbcare.followup.plat.service.impl;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;

import javax.annotation.Resource;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;

import redis.clients.jedis.JedisPool;

import com.alibaba.fastjson.JSONObject;
import com.bbcare.comm.AppException;
import com.bbcare.comm.Constants;
import com.bbcare.comm.ErrorCode;
import com.bbcare.comm.SeqUtil;
import com.bbcare.comm.ToolUtils;
import com.bbcare.department.plat.entity.DepartmentBasic;
import com.bbcare.department.plat.store.ibatis.IDeparmentBasicDao;
import com.bbcare.followup.plat.entity.ContentTempl;
import com.bbcare.followup.plat.entity.ContentTemplVersion;
import com.bbcare.followup.plat.entity.FollowQueue;
import com.bbcare.followup.plat.entity.Patient;
import com.bbcare.followup.plat.entity.PatientContentData;
import com.bbcare.followup.plat.entity.PtQueueExtend;
import com.bbcare.followup.plat.service.IPatientFollowService;
import com.bbcare.followup.plat.service.IPatientInfoHisService;
import com.bbcare.followup.plat.service.IPatientService;
import com.bbcare.followup.plat.store.ibatis.IConfCacheDAO;
import com.bbcare.followup.plat.store.ibatis.IContentTemplDAO;
import com.bbcare.followup.plat.store.ibatis.IFollowQueueDAO;
import com.bbcare.followup.plat.store.ibatis.IPatientDAO;
import com.bbcare.followup.plat.store.ibatis.IPatientOperationRecordDAO;
import com.bbcare.followup.plat.store.ibatis.IPatientTaskContentDAO;
import com.bbcare.followup.plat.store.ibatis.IPtQueueExtendDao;

/**
 * @name: 患者随访相关处理类接口实现
 * @author: DemonLee
 * @createTime: 2017.7.11
 * @description: 患者随访相关操作
 * @modify:
 *
 */
@Service
public class PatientFollowService implements IPatientFollowService {
    private final Log logger = LogFactory.getLog(PatientFollowService.class);

    @Autowired
    private IPatientOperationRecordDAO patientOperationRecordDao;

    @Autowired
    private IPatientDAO patientDao;

    @Autowired
    private IConfCacheDAO confCacheDao;

    @Autowired
    private IPatientService patientService;

    @Resource(name = "jedisPool")
    private JedisPool jedisPool;

    @Autowired
    private IPatientTaskContentDAO patientTaskConDao;

    @Autowired
    private IContentTemplDAO contentTemplDao;

    @Autowired
    private IPatientInfoHisService patientInfoHisService;

    @Autowired
    private IFollowQueueDAO queueDao;

    @Autowired
    private IPtQueueExtendDao ptQueueExtendDao;

    @Autowired
    private IDeparmentBasicDao deptBasicDao;

    // 查询随访评估量表内容模板通用接口实现
    @Override
    public Map<String, Object> getPatientFollowContTempl(Map<String, Object> paramIn) throws Exception {
        Map<String, Object> argMap = new HashMap<String, Object>(paramIn);
        Map<String, Object> retOut = new HashMap<String, Object>();

        String busiId = (String) argMap.get("busiId");
        // 根据静态配置表查询评估量表模板id
        Map<String, Object> staticMap = new HashMap<String, Object>();
        staticMap.put("type", Constants.FU_ASSESS_CONTTEMPL_TYPE);
        staticMap.put("paramCode", busiId);
        List<Map<String, Object>> staticList = confCacheDao.selectBsStaticParamByCondition(staticMap);
        if (!CollectionUtils.isEmpty(staticList)) {
            Map<String, Object> staticOut = new HashMap<String, Object>();
            Map<String, Object> contVerMap = new HashMap<String, Object>();
            Map<String, Object> dataOut = new HashMap<String, Object>();
            int quesSize = staticList.size();
            int kq = 0;
            String conTemplId = "";
            String paramName = "";
            List<Object> conDataList = new ArrayList<Object>();
            StringBuffer tmplVerList = new StringBuffer();
            for (kq = 0; kq < quesSize; kq++) {
                staticOut.clear();
                staticOut = staticList.get(kq);
                conTemplId = (String) staticOut.get("paramValue");
                paramName = (String) staticOut.get("paramName");
                if (StringUtils.isEmpty(conTemplId)) {
                    continue;
                }

                // 获取内容模板
                Map<String, Object> templMap = new HashMap<String, Object>();
                templMap.put("id", conTemplId);
                List<ContentTempl> ctList = contentTemplDao.selectTemplById(templMap);
                if (CollectionUtils.isEmpty(ctList)) {
                    continue;
                }
                ContentTempl conVo = ctList.get(0);

                // 获取内容模板版本
                contVerMap.clear();
                contVerMap.put("templId", conVo.getId());
                contVerMap.put("templVersion", conVo.getNewVersion());
                List<ContentTemplVersion> ctvList = contentTemplDao.selectContentDataNoTextByTempl(contVerMap);
                if (CollectionUtils.isEmpty(ctvList)) {
                    continue;
                }
                ContentTemplVersion ctv = ctvList.get(0);

                contVerMap.clear();
                dataOut.clear();
                contVerMap.put("templVersionId", ctv.getId());
                dataOut = patientService.getContTemplData(contVerMap);
                if (null != dataOut.get("contData")) {
                    conDataList.add(dataOut.get("contData"));
                    tmplVerList.append(ctv.getId());
                    tmplVerList.append(Constants.COMMA_SPLIT_STR);
                }
            }
            String tmplVerStr = tmplVerList.toString();
            tmplVerStr = tmplVerStr.substring(0, tmplVerStr.length() - 1);
            if (conDataList.size() > 0) {
                retOut.put("quesInfo", conDataList);
                retOut.put("quesName", paramName);
                retOut.put("tmplVerInfo", tmplVerStr);
            }
        }

        return retOut;
    }

    // 随访评估量表内容提交接口实现
    @Override
    @Transactional
    public Map<String, Object> savePtAssessContent(Map<String, Object> paramMap) throws Exception {
        Map<String, Object> argMap = new HashMap<String, Object>(paramMap);
        Map<String, Object> outMap = new HashMap<String, Object>();

        Map<String, Object> oprInfoMap = ToolUtils.typeCast(argMap.get("oprInfo"));
        Map<String, Object> busiInfo = ToolUtils.typeCast(argMap.get("busiInfo"));

        String authorName = (String) oprInfoMap.get("authorName");
        String updateTime = (String) oprInfoMap.get("updateTime");
        String authorId = (String) oprInfoMap.get("authorId");
        String updateAccept = (String) oprInfoMap.get("updateAccept");
        String tenantId = (String) oprInfoMap.get("tenantId");
        String opCode = (String) oprInfoMap.get("opCode");
        String opNote = (String) oprInfoMap.get("opNote");
        String opType = (String) oprInfoMap.get("opType");
        String sourceType = (String) oprInfoMap.get("sourceType");
        String busiId = (String) busiInfo.get("busiId");
        String userId = (String) busiInfo.get("patientId");
        String tmplVerInfo = (String) busiInfo.get("tmplVerInfo");

        outMap.put("updateAccept", updateAccept);
        outMap.put("patientId", userId);

        // 校验患者信息是否存在
        Map<String, Object> userMapIn = new HashMap<String, Object>();
        userMapIn.put("userId", userId);
        userMapIn.put("tenantId", tenantId);
        Patient ptVo = patientDao.selectById(userMapIn);
        if (null == ptVo || "".equals(ptVo.getId())) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_PATIENT_NOT_EXIST, "查询随访系统无此患者！"));
        }

        Map<String, Object> quesMap = (JSONObject) argMap.get("questiones");
        List<PatientContentData> ptcInList = new ArrayList<PatientContentData>();
        Iterator<String> iter = quesMap.keySet().iterator();
        while (iter.hasNext()) {
            PatientContentData pcdVo = new PatientContentData();
            String queskey = iter.next();
            String quesvalue = (String) quesMap.get(queskey);

            pcdVo.setContentId(busiId);
            pcdVo.setCreateTime(updateTime);
            pcdVo.setId(SeqUtil.getSeqNo(Constants.SEQ_NO_FOR_PTTASK_CONTDATAID));
            pcdVo.setQuestionAnswer(quesvalue);
            pcdVo.setQuestionId(queskey);
            pcdVo.setTaskId("");
            pcdVo.setUpdateAccept(updateAccept);
            pcdVo.setUpdateTime(updateTime);
            pcdVo.setUpdateType(Constants.UPDATE_TYPE_INSERT);
            pcdVo.setUserId(userId);
            pcdVo.setPtSchemeid("");
            pcdVo.setTemplType("");
            pcdVo.setOpTime("");
            pcdVo.setQueueId("");
            pcdVo.setTenantId(tenantId);
            pcdVo.setSourceTypeCreate(sourceType);
            pcdVo.setSourceTypeUpdate(sourceType);
            ptcInList.add(pcdVo);
        }
        // 批量插入
        if (ptcInList.size() > 0) {
            patientTaskConDao.savePatientTaskContentDataBatch(ptcInList);
            patientTaskConDao.savePatientTaskContentDataHisBatch(ptcInList);
        }

        // 入操作流水记录表 ia_operation_record
        Map<String, Object> paramRecord = new HashMap<String, Object>();
        paramRecord.put("userName", ptVo.getUserName());
        paramRecord.put("userId", userId);
        paramRecord.put("queueId", "");
        paramRecord.put("authorId", authorId);
        paramRecord.put("opTime", updateTime);
        paramRecord.put("type", Constants.PATIENT_ACTIVE_BUSI_TYPE_13);
        paramRecord.put("opUsertype", Constants.OPCODE_TYPE_DOCTOR);
        paramRecord.put("authorName", authorName);
        paramRecord.put("opCode", opCode);
        paramRecord.put("updateAccept", updateAccept);
        paramRecord.put("tenantId", tenantId);
        paramRecord.put("remark", opNote);
        paramRecord.put("opType", opType);
        paramRecord.put("taskId", "");
        paramRecord.put("busiId", busiId);
        paramRecord.put("breifIntro", tmplVerInfo);
        Map<String, Object> outRecord = patientInfoHisService.buildOperationRecord(paramRecord);
        patientOperationRecordDao.saveOperationRecord(outRecord);

        return outMap;
    }

    // 查询随访评估量表某次记录详情接口实现
    @Override
    public Map<String, Object> getPtFuAssessContInfo(Map<String, Object> paramIn) throws Exception {
        Map<String, Object> argMap = new HashMap<String, Object>(paramIn);
        Map<String, Object> retOut = new HashMap<String, Object>();

        String patientId = (String) argMap.get("patientId");
        String updateAccept = (String) argMap.get("updateAccept");
        String busiId = (String) argMap.get("busiId");

        // 根据流水查询模板id
        Map<String, Object> iaIn = new HashMap<String, Object>();
        iaIn.put("updateAccept", updateAccept);
        iaIn.put("userId", patientId);
        iaIn.put("busiId", busiId);
        List<Map<String, Object>> iaOutList = patientOperationRecordDao.selectOperationByUserId(iaIn);
        if (CollectionUtils.isEmpty(iaOutList)) {
            throw (new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_PATIENT_IAOPR_RECORD_NOT_EXISTS, "未查询到对应操作记录！"));
        }

        // 问卷模板
        Map<String, Object> iaOut = iaOutList.get(0);
        String breifIntr = (String) iaOut.get("BREIF_INTRO");
        if (StringUtils.isEmpty(breifIntr)) {
            Map<String, Object> cntTempIn = new HashMap<String, Object>();
            cntTempIn.put("busiId", busiId);
            retOut = this.getPatientFollowContTempl(cntTempIn);
        } else {
            List<Object> conDataList = new ArrayList<Object>();
            String templVerArr[] = breifIntr.split(Constants.COMMA_SPLIT_STR);
            int asize = templVerArr.length;
            int kk = 0;
            Map<String, Object> contVerMap = new HashMap<String, Object>();
            Map<String, Object> dataOut = new HashMap<String, Object>();
            for (kk = 0; kk < asize; kk++) {
                contVerMap.clear();
                dataOut.clear();
                if (!StringUtils.isEmpty(templVerArr[kk])) {
                    contVerMap.put("templVersionId", templVerArr[kk]);
                    dataOut = patientService.getContTemplData(contVerMap);
                    if (null != dataOut.get("contData")) {
                        conDataList.add(dataOut.get("contData"));
                    }
                }
            }
            if (conDataList.size() > 0) {
                retOut.put("quesInfo", conDataList);
            } else {
                throw new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_QUES_TEMPL_NOT_EXIST, "未查询到任务内容模板记录！");
            }
        }

        // 根据流水查询答案
        HashMap<String, Object> questionMap = new HashMap<String, Object>();
        Map<String, Object> valMapIn = new HashMap<String, Object>();
        valMapIn.put("contentId", busiId);
        valMapIn.put("userId", patientId);
        valMapIn.put("updateAccept", updateAccept);
        List<PatientContentData> ptTaskConList = patientTaskConDao.listCntDataByUserIdAndAccept(valMapIn);
        int k = 0;
        for (; k < ptTaskConList.size(); k++) {
            PatientContentData pcdVo = ptTaskConList.get(k);
            questionMap.put(pcdVo.getQuestionId(), pcdVo.getQuestionAnswer());
        }
        retOut.put("values", questionMap);

        return retOut;
    }

    // 查询随访评估量表记录list接口实现
    public HashMap<String, Object> listPtFuAsses(Map<String, Object> paramMap) throws Exception {
        Map<String, Object> argMap = new HashMap<String, Object>(paramMap);
        HashMap<String, Object> retMap = new HashMap<String, Object>();
        List<Map<String, Object>> pqsList = new ArrayList<Map<String, Object>>();

        String extendValue1 = "";
        String extendValue2 = "";
        String extendValue3 = "";
        String busiId = (String) argMap.get("busiId");
        // 根据静态配置表查询评估量表模板id
        Map<String, Object> staticMap = new HashMap<String, Object>();
        staticMap.put("type", Constants.FU_ASSESS_CONTTEMPL_TYPE);
        staticMap.put("paramCode", busiId);
        List<Map<String, Object>> staticList = confCacheDao.selectBsStaticParamByTypeAndCode(staticMap);
        if (!CollectionUtils.isEmpty(staticList)) {
            Map<String, Object> staticOut = staticList.get(0);
            extendValue1 = (String) staticOut.get("extend_value1");
            extendValue2 = (String) staticOut.get("extend_value2");
            extendValue3 = (String) staticOut.get("extend_value3");
        } else {
            throw new AppException(ErrorCode.FOLLOWUP_EXCEPTION_TYPE_STATIC_CONFIG_NOT_EXIST, "未查询到业务id对应配置记录！");
        }
        Map<String, Object> extInfo = new HashMap<String, Object>();
        extInfo.put("listName", extendValue1);
        extInfo.put("quesName", extendValue2);
        extInfo.put("recordName", extendValue3);
        retMap.put("extInfo", extInfo);

        int total = patientOperationRecordDao.countPtFuAssess(argMap);
        if (0 != total) {
            pqsList = patientOperationRecordDao.listPtFuAssess(argMap);
            if (CollectionUtils.isEmpty(pqsList)) {
                total = 0;
            }
        }

        retMap.put("total", total);
        retMap.put("rows", pqsList);

        return retMap;
    }

    // 查询患者样本采集状态列表list接口实现
    public Map<String, Object> listPtSample(Map<String, Object> paramMap) throws Exception {
        Map<String, Object> argMap = new HashMap<String, Object>(paramMap);
        HashMap<String, Object> retMap = new HashMap<String, Object>();
        List<Map<String, Object>> pqsList = new ArrayList<Map<String, Object>>();
        retMap.put("total", 0);
        retMap.put("rows", pqsList);

        List<String> queueIdArray = new ArrayList<String>();
        String tenantId = (String) argMap.get("tenantId");
        String queueId = (String) argMap.get("queueId");
        String authorId = (String) argMap.get("authorId");
        String sampleCode = (String) argMap.get("sampleCode");

        if (!StringUtils.isEmpty(queueId)) {
            queueIdArray.add(queueId);
        } else {
            List<FollowQueue> fqList = new ArrayList<FollowQueue>();
            HashMap<String, Object> qryQueueMap = new HashMap<String, Object>();
            qryQueueMap.put("authorId", authorId);
            qryQueueMap.put("queueStatus", Constants.QUEUE_STATUS_NOMAL);// 队列状态正常
            qryQueueMap.put("tenantId", tenantId);
            qryQueueMap.put("queueTypePrivate", Constants.QUEUE_TYPE_PRIVATE);
            qryQueueMap.put("queueTypeTenant", Constants.QUEUE_TYPE_TENANT);
            qryQueueMap.put("queueTypePublic", Constants.QUEUE_TYPE_PUBLIC);

            fqList = queueDao.selectQueueIdByAuthority(qryQueueMap);
            if (CollectionUtils.isEmpty(fqList)) {
                logger.warn("该账号无可查看到的队列信息...arg==" + qryQueueMap.toString());
                return retMap;
            }
            int fqt = 0;
            for (fqt = 0; fqt < fqList.size(); fqt++) {
                FollowQueue fqVo = fqList.get(fqt);
                queueIdArray.add(fqVo.getId());
            }
        }

        argMap.put("queueIdIn", queueIdArray);
        argMap.put("userStatus", Constants.PATIENT_QUEUESCHEME_USER_STATUS_NOMAL);// 队列中正常状态下的用户
        argMap.put("staticType", Constants.PT_BIOLOGY_SAMPLE_TYPE);// type=1010
        argMap.put("paramCode", sampleCode);// 生物样本

        int total = patientOperationRecordDao.countPtBioSample(argMap);
        if (0 != total) {
            pqsList = patientOperationRecordDao.listPtBioSample(argMap);
            if (CollectionUtils.isEmpty(pqsList)) {
                total = 0;
            } else {
                int pq = 0;
                String sampleName = "";
                String patientId = "";
                String patientSchemeId = "";
                Map<String, Object> extIn = new HashMap<String, Object>();
                for (; pq < pqsList.size(); pq++) {
                    extIn.clear();
                    Map<String, Object> pqsMap = pqsList.get(pq);
                    sampleName = (String) pqsMap.get("sampleType");
                    patientId = (String) pqsMap.get("patientId");
                    patientSchemeId = (String) pqsMap.get("patientSchemeId");
                    extIn.put("userId", patientId);
                    extIn.put("patientSchemeId", patientSchemeId);
                    extIn.put("paramName", sampleName);
                    extIn.put("paramType", sampleCode);
                    List<PtQueueExtend> ptQueueExtList = ptQueueExtendDao.listPtQueueExtend(extIn);
                    if (CollectionUtils.isEmpty(ptQueueExtList)) {
                        pqsMap.put("sampleValue1", "");
                        pqsMap.put("sampleValue2", "");
                        pqsMap.put("sampleValue3", "");
                    } else {
                        PtQueueExtend ptQueueExtVo = ptQueueExtList.get(0);
                        pqsMap.put("sampleValue1", ptQueueExtVo.getExtendValue1());
                        pqsMap.put("sampleValue2", ptQueueExtVo.getExtendValue2());
                        pqsMap.put("sampleValue3", ptQueueExtVo.getExtendValue3());
                    }

                    pqsMap.put("age", ToolUtils.getAgeMonDayByBirthday("" + pqsMap.get("birthday")));
                    pqsMap.put("pregnancyWeek",
                            ToolUtils.getPregnancyStr(Integer.parseInt("" + pqsMap.get("pregnancyDay"))));
                }
            }
        }

        retMap.put("total", total);
        retMap.put("rows", pqsList);

        return retMap;
    }

    // 查询医院科室信息接口实现
    @Override
    public Map<String, Object> getHospitalInfo(Map<String, Object> paramIn) throws Exception {
        Map<String, Object> argMap = new HashMap<String, Object>(paramIn);
        Map<String, Object> retOut = new HashMap<String, Object>();
        List<DepartmentBasic> deptList = deptBasicDao.selectByTenantIdAndId(argMap);
        if (0 != deptList.size()) {
            DepartmentBasic deptVo = deptList.get(0);
            retOut.put("hospitalName", deptVo.getHospName());
            retOut.put("deptName", deptVo.getDeptName());
        }

        return retOut;
    }

}
